#include "systemthemedetector.h"
#include <QDebug>
#include <QTimer>
#include <QFileSystemWatcher>

#ifdef Q_OS_MACOS
#include <objc/objc.h>
#include <objc/message.h>
#include <objc/runtime.h>
#endif

#ifdef Q_OS_WIN
#include <windows.h>
#include <winreg.h>
#endif

#ifdef Q_OS_UNIX
#ifndef Q_OS_MACOS
#include <QProcess>
#include <QFile>
#include <QDir>
#include <QSettings>
#endif
#endif

SystemThemeDetector::SystemThemeDetector(QObject *parent)
    : QObject(parent)
{
    m_lastState = isDarkMode();
}

SystemThemeDetector::~SystemThemeDetector()
{
    stopWatching();
}

bool SystemThemeDetector::isDarkMode()
{
#ifdef Q_OS_MACOS
    // macOS: 检查 AppleInterfaceStyle
    id userDefaults = reinterpret_cast<id (*)(Class, SEL)>(objc_msgSend)(
        objc_getClass("NSUserDefaults"),
        sel_registerName("standardUserDefaults")
    );
    
    id key = reinterpret_cast<id (*)(Class, SEL, const char*)>(objc_msgSend)(
        objc_getClass("NSString"),
        sel_registerName("stringWithUTF8String:"),
        "AppleInterfaceStyle"
    );
    
    id style = reinterpret_cast<id (*)(id, SEL, id)>(objc_msgSend)(
        userDefaults,
        sel_registerName("stringForKey:"),
        key
    );
    
    if (style) {
        const char* styleStr = reinterpret_cast<const char* (*)(id, SEL)>(objc_msgSend)(
            style,
            sel_registerName("UTF8String")
        );
        return styleStr && QString(styleStr).contains("Dark", Qt::CaseInsensitive);
    }
    return false;

#elif defined(Q_OS_WIN)
    // Windows: 检查注册表
    DWORD value = 1; // 默认亮色
    DWORD valueSize = sizeof(value);
    
    LSTATUS result = RegGetValueW(
        HKEY_CURRENT_USER,
        L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
        L"AppsUseLightTheme",
        RRF_RT_DWORD,
        nullptr,
        &value,
        &valueSize
    );
    
    if (result == ERROR_SUCCESS) {
        return value == 0; // 0=暗色, 1=亮色
    }
    return false;

#elif defined(Q_OS_UNIX)
    // Linux: 尝试多种方法检测

    // 获取桌面环境信息
    QByteArray desktop = qgetenv("XDG_CURRENT_DESKTOP").toLower();
    qDebug() << "Linux desktop environment:" << desktop;

    // 方法1: GNOME/Ubuntu - 优先检查 color-scheme
    if (desktop.contains("gnome") || desktop.contains("ubuntu")) {
        // 优先检查 color-scheme，这是更准确的主题检测方式
        QProcess colorScheme;
        colorScheme.start("gsettings", QStringList() << "get" << "org.gnome.desktop.interface" << "color-scheme");

        if (colorScheme.waitForFinished(1000)) {
            QString scheme = QString::fromLocal8Bit(colorScheme.readAllStandardOutput()).trimmed();
            // gsettings 返回的值带引号，如 'prefer-dark'，需要去除
            scheme = scheme.remove('\'').remove('"');
            qDebug() << "GNOME color scheme:" << scheme;
            if (scheme == "prefer-dark") {
                qDebug() << "Detected dark mode from color-scheme";
                return true;
            } else if (scheme == "prefer-light") {
                qDebug() << "Detected light mode from color-scheme";
                return false;
            }
        }

        // 备用方法：检查 GTK 主题名称
        QProcess gsettings;
        gsettings.start("gsettings", QStringList()
            << "get"
            << "org.gnome.desktop.interface"
            << "gtk-theme");

        if (gsettings.waitForFinished(1000)) {
            QString output = QString::fromLocal8Bit(gsettings.readAllStandardOutput()).trimmed();
            output = output.remove('\'').remove('"');
            qDebug() << "GNOME GTK theme:" << output;
            if (output.contains("dark", Qt::CaseInsensitive)) {
                qDebug() << "Detected dark mode from GTK theme";
                return true;
            }
        }
    }
    
    // 方法2: KDE - 检查配置文件
    QString kdeglobals = QDir::homePath() + "/.config/kdeglobals";
    if (QFile::exists(kdeglobals)) {
        QSettings kdeSettings(kdeglobals, QSettings::IniFormat);
        QString colorScheme = kdeSettings.value("General/ColorScheme", "").toString();
        if (colorScheme.contains("Dark", Qt::CaseInsensitive)) {
            return true;
        }
    }
    
    // 方法3: 检查 GTK3 主题
    QString gtk3Config = QDir::homePath() + "/.config/gtk-3.0/settings.ini";
    if (QFile::exists(gtk3Config)) {
        QSettings gtkSettings(gtk3Config, QSettings::IniFormat);
        QString themeName = gtkSettings.value("Settings/gtk-theme-name", "").toString();
        if (themeName.contains("dark", Qt::CaseInsensitive)) {
            return true;
        }
    }
    
    return false;
#else
    return false;
#endif
}

void SystemThemeDetector::startWatching()
{
    setupPlatformWatcher();
}

void SystemThemeDetector::stopWatching()
{
#ifdef Q_OS_MACOS
    if (m_macObserver) {
        // 移除观察者
        id notificationCenter = reinterpret_cast<id (*)(Class, SEL)>(objc_msgSend)(
            objc_getClass("NSNotificationCenter"),
            sel_registerName("defaultCenter")
        );
        
        reinterpret_cast<void (*)(id, SEL, id)>(objc_msgSend)(
            notificationCenter,
            sel_registerName("removeObserver:"),
            reinterpret_cast<id>(m_macObserver)
        );
        
        m_macObserver = nullptr;
    }
#endif

#ifdef Q_OS_UNIX
#ifndef Q_OS_MACOS
    if (m_fileWatcher) {
        delete m_fileWatcher;
        m_fileWatcher = nullptr;
    }
    if (m_pollTimer) {
        m_pollTimer->stop();
        delete m_pollTimer;
        m_pollTimer = nullptr;
    }
#endif
#endif
}

void SystemThemeDetector::setupPlatformWatcher()
{
#ifdef Q_OS_MACOS
    setupMacOSWatcher();
#elif defined(Q_OS_WIN)
    setupWindowsWatcher();
#elif defined(Q_OS_UNIX)
    setupLinuxWatcher();
#endif
}

#ifdef Q_OS_MACOS
void SystemThemeDetector::setupMacOSWatcher()
{
    // macOS: 监听 AppleInterfaceThemeChangedNotification
    // 注意：这里需要在Objective-C++环境中实现完整的观察者模式
    // 简化版本：使用定时器轮询
    QTimer* timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, [this]() {
        bool currentState = isDarkMode();
        if (currentState != m_lastState) {
            m_lastState = currentState;
            emit themeChanged(currentState);
            qDebug() << "macOS theme changed to:" << (currentState ? "Dark" : "Light");
        }
    });
    timer->start(2000); // 每2秒检查一次
}
#endif

#ifdef Q_OS_WIN
void SystemThemeDetector::setupWindowsWatcher()
{
    // Windows: 使用定时器轮询注册表
    // 更好的方式是监听注册表变化，但需要更复杂的实现
    QTimer* timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, [this]() {
        bool currentState = isDarkMode();
        if (currentState != m_lastState) {
            m_lastState = currentState;
            emit themeChanged(currentState);
            qDebug() << "Windows theme changed to:" << (currentState ? "Dark" : "Light");
        }
    });
    timer->start(2000); // 每2秒检查一次
}
#endif

#ifdef Q_OS_UNIX
#ifndef Q_OS_MACOS
void SystemThemeDetector::setupLinuxWatcher()
{
    // Linux: 使用定时轮询，因为文件监听在Linux下不可靠
    // 特别是对于gsettings管理的dconf设置

    // 备用方案：配置文件监听（适用于非GNOME环境）
    m_fileWatcher = new QFileSystemWatcher(this);

    QStringList watchPaths;
    watchPaths << QDir::homePath() + "/.config/gtk-3.0/settings.ini";
    watchPaths << QDir::homePath() + "/.config/kdeglobals";

    for (const QString& path : watchPaths) {
        if (QFile::exists(path)) {
            m_fileWatcher->addPath(path);
            qDebug() << "Watching theme config file:" << path;
        }
    }

    connect(m_fileWatcher, &QFileSystemWatcher::fileChanged, this, [this](const QString& path) {
        qDebug() << "Theme config file changed:" << path;
        bool currentState = isDarkMode();
        if (currentState != m_lastState) {
            m_lastState = currentState;
            emit themeChanged(currentState);
            qDebug() << "Linux theme changed (file watch) to:" << (currentState ? "Dark" : "Light");
        }
    });

    // 主要方案：定时轮询gsettings（适用于GNOME等现代桌面环境）
    m_pollTimer = new QTimer(this);
    connect(m_pollTimer, &QTimer::timeout, this, [this]() {
        bool currentState = isDarkMode();
        if (currentState != m_lastState) {
            m_lastState = currentState;
            emit themeChanged(currentState);
            qDebug() << "Linux theme changed (polling) to:" << (currentState ? "Dark" : "Light");
        }
    });
    m_pollTimer->start(2000); // 每2秒检查一次，提高响应速度
}
#endif
#endif

